package it.trekker.rest;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import it.trekker.converter.IJsonConverter;
import it.trekker.converter.JsonConverter;
import it.trekker.dao.Excursion;
import it.trekker.dao.ExcursionCoordinate;
import it.trekker.dao.IExcursionCoordinateDAO;
import it.trekker.dao.IExcursionDAO;
import it.trekker.dao.IPoiDAO;
import it.trekker.dao.IUserDAO;
import it.trekker.dao.Poi;
import it.trekker.dao.User;
import it.trekker.upload.json.ExcursionAdapter;
import javax.annotation.ManagedBean;
import javax.ejb.EJB;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.jboss.resteasy.plugins.providers.multipart.InputPart;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;

@Path("/upload")
@ManagedBean
public class UploadJsonREST {

	private static final Logger logger = Logger.getLogger(UploadJsonREST.class.getSimpleName());
	
	@EJB
	IUserDAO userDAO;
	@EJB
	IExcursionDAO excursionDAO;
	@EJB
	IExcursionCoordinateDAO excursionCoordDAO;
	@EJB
	IPoiDAO poiDAO;

//	@POST
//	@Path("/json")
//	@Consumes("application/json")
//	public Response uploadJsonFile(ExcursionAdapter[] list) {
//		for(ExcursionAdapter excursionAdapter : list) {
//
//			User user = excursionAdapter.getUser();
//			user.setId(userDAO.insert(user));
//
//			Excursion excursion = excursionAdapter.getExcursion();
//			excursion.setUser(user);
//			excursion.setId(excursionDAO.insert(excursion));
//
//			List<ExcursionCoordinate> coordinates = excursionAdapter.getCoordinates();
//			for(ExcursionCoordinate coord : coordinates) {
//				coord.setExcursion(excursion);
//				coord.setId(excursionCoordDAO.insert(coord));
//			}
//
//			List<Poi> pois = excursionAdapter.getPois();
//			for(Poi poi : pois) {
//				poi.setExcursion(excursion);
//				poi.setId(poiDAO.insert(poi));
//			}
//
//		}
//
//		return Response.ok().build();
//	}

	@POST
	@Path("/json")
	@Consumes(MediaType.MULTIPART_FORM_DATA)
//	@Produces(MediaType.APPLICATION_JSON)
	public Response uploadJsonFile(MultipartFormDataInput input) {

		Map<String, List<InputPart>> uploadForm = input.getFormDataMap();
		List<InputPart> inputParts = uploadForm.get("fileUp");
		for(InputPart inputPart : inputParts) {

			try {

				MultivaluedMap<String, String> header = inputPart.getHeaders();

				//convert the uploaded file to inputstream
				InputStream inputStream = inputPart.getBody(InputStream.class, null);

				byte[] bytes = IOUtils.toByteArray(inputStream);
				String json = new String(bytes);
				
				IJsonConverter converter = new JsonConverter();
				ExcursionAdapter[] excursionAdapterArray = converter.Json2ExcursionAdapterArray(json);

				saveInDatabase(excursionAdapterArray);

			} catch (IOException e) {
				e.printStackTrace();
			}

		}

		return Response.ok().entity("Upload succesful!").build();
//		return new UploadResult(UploadResult.OK, null);
	}
	
	@POST
	@Path("/json")
	public Response uploadJsonFile(String json) {
		logger.info(json);
		
		IJsonConverter converter = new JsonConverter();
		ExcursionAdapter[] list = converter.Json2ExcursionAdapterArray(json);
		
		saveInDatabase(list);

		return Response.ok().build();
	}

	
	private void saveInDatabase(ExcursionAdapter[] list) {
		for(ExcursionAdapter excursionAdapter : list) {

			User user = excursionAdapter.getUser();
			User userFound = userDAO.findUserByName(user.getUsername());
			if(userFound == null)
				user.setId(userDAO.insert(user));
			else
				user = userFound;

			Excursion excursion = excursionAdapter.getExcursion();
			excursion.setUser(user);
			excursion.setId(excursionDAO.insert(excursion));

			List<ExcursionCoordinate> coordinates = excursionAdapter.getCoordinates();
			for(ExcursionCoordinate coord : coordinates) {
				coord.setExcursion(excursion);
				coord.setId(excursionCoordDAO.insert(coord));
			}

			List<Poi> pois = excursionAdapter.getPois();
			for(Poi poi : pois) {
				poi.setExcursion(excursion);
				poi.setId(poiDAO.insert(poi));
			}

		}
	}
}
